﻿namespace Nomo.CoreModule
{
    /// <summary>
    /// 表示 Unix 时间戳。
    /// </summary>
    public readonly struct UnixTimeStamp : System.IEquatable<UnixTimeStamp>
    {
        private const    long DateTime19700101Ticks = 621355968000000000L;
        private const    long TicksPerSecond        = 10000000L;
        private readonly long _second;

        private UnixTimeStamp(long second)
        {
            _second = second;
        }

        /// <summary>
        /// 将时刻转换为 Unix 时间戳。
        /// </summary>
        /// <param name="dateTime">时刻。</param>
        /// <returns>Unix 时间戳。</returns>
        public static explicit operator UnixTimeStamp(System.DateTime dateTime)
        {
            return new UnixTimeStamp((dateTime.ToUniversalTime().Ticks - DateTime19700101Ticks) / TicksPerSecond);
        }

        /// <summary>
        /// 将 Unix 时间戳转换为时刻。
        /// </summary>
        /// <param name="unixTimeStamp">Unix 时间戳。</param>
        /// <returns>时刻。</returns>
        public static explicit operator System.DateTime(UnixTimeStamp unixTimeStamp)
        {
            return new System.DateTime(unixTimeStamp._second * TicksPerSecond + DateTime19700101Ticks).ToLocalTime();
        }

        /// <summary>
        /// 将表示 Unix 时间戳的秒数转换为 Unix 时间戳。
        /// </summary>
        /// <param name="second">表示 Unix 时间戳的秒数。</param>
        /// <returns>Unix 时间戳。</returns>
        public static explicit operator UnixTimeStamp(long second)
        {
            return new UnixTimeStamp(second);
        }

        /// <summary>
        /// 将 Unix 时间戳转换为表示 Unix 时间戳的秒数。
        /// </summary>
        /// <param name="unixTimeStamp">Unix 时间戳。</param>
        /// <returns>表示 Unix 时间戳的秒数。</returns>
        public static explicit operator long(UnixTimeStamp unixTimeStamp)
        {
            return unixTimeStamp._second;
        }

        /// <inheritdoc />
        public bool Equals(UnixTimeStamp other)
        {
            return _second == other._second;
        }

        /// <inheritdoc />
        public override bool Equals(object obj)
        {
            return obj is UnixTimeStamp unixTimeStamp && Equals(unixTimeStamp);
        }

        /// <inheritdoc />
        public override int GetHashCode()
        {
            return _second.GetHashCode();
        }

        /// <inheritdoc />
        public override string ToString()
        {
            return $"{(System.DateTime) this} ({_second})";
        }
    }
}
